﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace ttg_internal.utils
{
    /// <summary>
    /// Contains perfomance information as 2D table.
    /// </summary>
    public class PerfTable : PerfElement
    {
        #region properties

        private string[,] _values;

        /// <summary>
        /// Returns table elements.
        /// </summary>
        public string[,] Values
        {
            get
            {
                return _values;
            }
        }
        private string[] _xLegends;

        /// <summary>
        /// Returns labels for x-axis.
        /// </summary>
        public string[] XLegends
        {
            get
            {
                return _xLegends;
            }
        }

        private string[] _yLegends;

        /// <summary>
        /// Returns labels for y-axis.
        /// </summary>
        public string[] YLegends
        {
            get
            {
                return _yLegends;
            }
        }

        #endregion

        /// <summary>
        /// Creates table with given axes.
        /// </summary>
        public PerfTable(string Name, string Description, string[] XLegends, string[] YLegends)
            :base(Name, Description)
        {
            this._xLegends = XLegends;
            this._yLegends = YLegends;
            this._values = new string[XLegends.Length, YLegends.Length];
        }

        public PerfTable(string Name, string[] XLegends, string[] YLegends)
            : this(Name, "Not provided", XLegends, YLegends)
        {
        }

        /// <summary>
        /// Adds given value to cell, located at (X, Y).
        /// </summary>
        public void AddValue(int X, int Y, string Value)
        {
            if (0 <= X && X < XLegends.Length &&
                0 <= Y && Y < YLegends.Length)
            {
                Values[X, Y] = Value;
            }
        }

        public override void SaveToXml(System.Xml.XmlDocument doc, System.Xml.XmlNode parent)
        {
            XmlNode root = parent.AppendChild(doc.CreateElement(this.Name));
            //Storing description.
            if (this.Description != null && this.Description != "")
            {
                XmlNode desc = doc.CreateElement("Description");
                root.AppendChild(desc);
                desc.AppendChild(doc.CreateTextNode(this.Description));
            }
            //Creating table header.
            XmlNode vals = root.AppendChild(doc.CreateElement("Values"));
            XmlNode width = vals.AppendChild(doc.CreateElement("Width"));
            width.AppendChild(doc.CreateTextNode(XLegends.Length.ToString()));
            XmlNode height = vals.AppendChild(doc.CreateElement("Height"));
            height.AppendChild(doc.CreateTextNode(YLegends.Length.ToString()));
            //Storing XLegend and YLegend 
            foreach (string legend in XLegends)
            {
                vals.AppendChild(doc.CreateElement("XLegend")).AppendChild(doc.CreateTextNode(legend));
            }
            foreach (string legend in YLegends)
            {
                vals.AppendChild(doc.CreateElement("YLegend")).AppendChild(doc.CreateTextNode(legend));
            }
            //Storing table content.
            for (int y = 0; y < Values.GetLength(1); y++)
            {
                XmlNode row = vals.AppendChild(doc.CreateElement("Row"));
                for (int x = 0; x < Values.GetLength(0); x++)
                    row.AppendChild(doc.CreateElement("Value")).AppendChild(doc.CreateTextNode(Values[x, y]));
            }
            //Storing childs.
            foreach (PerfElement el in Childs)
                el.SaveToXml(doc, root);
        }

        public override void SaveToHtml(StringBuilder html)
        {
            //Creating header.
            html.Append(String.Format("{0}: {1} <BR/>" + Environment.NewLine,
                                      Name, Description));
            //Storing childs.
            foreach (PerfElement el in Childs)
                el.SaveToHtml(html);
        }
    }
}
